package cn.sunjinxin.trade.domain.model;


import cn.sunjinxin.trade.domain.enums.CurrencyType;
import cn.sunjinxin.trade.domain.enums.FundType;
import cn.sunjinxin.trade.domain.even.TradeEvent;
import cn.sunjinxin.trade.domain.statemachine.FundStateMachine;
import cn.sunjinxin.trade.domain.statemachine.OrderStateMachine;
import cn.sunjinxin.trade.domain.status.FundStatus;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.Setter;

import java.util.Date;

/**
 * 资金单
 *
 * @author issavior
 */
@Getter
@Setter
public class FundOrder {

    /**
     * 资金单Id
     */
    private Long id;

    /**
     * 资金单类型
     */
    private FundType fundType;

    /**
     * 创建时间
     */
    private Date createdTime;

    /**
     * 修改时间
     */
    private Date updatedTime;

    /**
     * 订单id
     */
    private Long orderId;

    /**
     * 退款单id
     */
    private Long refundOrderId;

    /**
     * 付款方名称
     */
    private String payerNick;

    /**
     * 付款方账号id
     */
    private String payerAccountId;

    /**
     * 付款方账号类型
     */
    private String payerAccountType;

    /**
     * 收款方账号id
     */
    private String receiverAccountId;

    /**
     * 收款方名称
     */
    private String receiverNick;

    /**
     * 收款方账号类型
     */
    private String receiverAccountType;

    /**
     * 外部支付订单号（支付退款流水号）
     */
    private String outPayOrderId;

    /**
     * 资金单状态
     */
    private FundStatus status;

    /**
     * 支付总金额
     */
    private Long payFee;

    /**
     * 支付时间
     */
    private Date payTime;

    /**
     * 币种
     */
    private CurrencyType currencyType;

    /**
     * 扩展属性
     */
    private JSONObject attributes = new JSONObject();

    public static FundOrder init() {
        FundOrder fundOrder = new FundOrder();
        fundOrder.status = FundStatus.INIT;
        return fundOrder;
    }

    public FundOrder push(TradeEvent tradeEvent) {
        this.status = FundStateMachine.INSTANCE.transition(this.status, tradeEvent);
        return this;
    }

    public boolean isEnd() {
        return FundStatus.PAY_FAIL == status || FundStatus.PAY_SUCCESS == status;
    }

    public boolean isFailEnd() {
        return FundStatus.PAY_FAIL == status;
    }

    public boolean isSuccessEnd() {
        return FundStatus.PAY_SUCCESS == status;
    }

    /**
     * 获取支付单标题
     *
     * @return
     */
    public String getSubject() {
        Object subject = attributes.get("subject");
        if (subject == null) {
            return null;
        }
        return String.valueOf(subject);
    }

    /**
     * 设置支付单标题
     *
     * @param subject
     */
    public void setSubject(String subject) {
        attributes.put("subject", subject);
    }

    public void idempotent() {
        if (this.status == FundStatus.PAY_SUCCESS) {
            throw new RuntimeException("资金单异常");
        }
    }
}

